package com.ingenico.insider;

import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.Box;
import javax.swing.ImageIcon;
import javax.swing.JMenuBar;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

import com.ingenico.insider.services.impl.BirdsEyeViewSupplier;
import com.ingenico.insider.services.impl.CanvasSupplier;
import com.ingenico.insider.services.impl.CoordinatesSupplier;
import com.ingenico.insider.services.impl.CurvePropertyControlSupplier;
import com.ingenico.insider.services.impl.CurvesControlSupplier;
import com.ingenico.insider.services.impl.CurvesSupplier;
import com.ingenico.insider.services.impl.DebugSupplier;
import com.ingenico.insider.services.impl.DockableViewsSupplier;
import com.ingenico.insider.services.impl.HelpSupplier;
import com.ingenico.insider.services.impl.LayoutControlSupplier;
import com.ingenico.insider.services.impl.LocalisationSupplier;
import com.ingenico.insider.services.impl.NotificationSupplier;
import com.ingenico.insider.services.impl.SelectionControlSupplier;
import com.ingenico.insider.services.impl.SelectionLayerSupplier;
import com.ingenico.insider.services.impl.StandardMenuSupplier;
import com.ingenico.insider.services.impl.ThemesMenuSupplier;
import com.ingenico.insider.services.impl.UserPreferencesSupplier;
import com.ingenico.insider.services.impl.ViewsMenuSupplier;
import com.ingenico.insider.services.impl.ZoomControlSupplier;
import com.ingenico.insider.util.Constants;

public class Main {
	private static final Logger _logger = Logger.getLogger(Main.class.getCanonicalName());
	
	// re-use the DockableViesSupplier resource bundle
	private static final ResourceBundle resourceBundle = ResourceBundle.getBundle(DockableViewsSupplier.class.getSimpleName());

	/**
	 * Public constant keywords
	 */
	public static final String FRAME_TITLE_PATH = Constants.INSIDER_BASE + Constants.SEPARATOR  + LocalisationSupplier.TITLE_KEY;
	public static final String WIDTH_PATH = Constants.INSIDER_BASE + Constants.SEPARATOR + "width";
	public static final String HEIGHT_PATH = Constants.INSIDER_BASE + Constants.SEPARATOR + "height";
	public static final String EXTENDED_STATE_PATH = Constants.INSIDER_BASE + Constants.SEPARATOR + "extended_state";

	public static void main(final String[] args) throws Exception {
		if (_logger.isLoggable(Level.FINEST)) {
			StackTraceElement stackTop = Thread.currentThread().getStackTrace()[1];
			_logger.entering(stackTop.getClassName(), stackTop.getMethodName(), args);
		}

		UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

		SwingUtilities.invokeLater(new Runnable() {

			public void run() {
				DockableViewsSupplier frame = null;

				String resourceString = null;
				try {
					// Get the frame instance
					frame = DockableViewsSupplier.getInstance();

					CanvasSupplier.getInstance();

					ThemesMenuSupplier.getInstance();
					ViewsMenuSupplier.getInstance();

					BirdsEyeViewSupplier.getInstance();

					CurvesSupplier.getInstance();
					CurvesControlSupplier.getInstance();
					CurvePropertyControlSupplier.getInstance();

					CoordinatesSupplier.getInstance();

					ZoomControlSupplier.getInstance();

// This has been moved in the CurvePropertyControlSupplier
//					ResamplingControlSupplier.getInstance();

					SelectionLayerSupplier.getInstance();
					SelectionControlSupplier.getInstance();

// The DebugSupplier provides a debug menu and a javascript engine
					DebugSupplier.getInstance();

					HelpSupplier.getInstance();

					// We definitely want to load the default layout !
					LayoutControlSupplier.getInstance().loadDefault();

					// Set the frame menu bar
					JMenuBar menuBar = new JMenuBar();
					menuBar.add(StandardMenuSupplier.getInstance().getFileMenu());
					menuBar.add(StandardMenuSupplier.getInstance().getEditMenu());
					menuBar.add(StandardMenuSupplier.getInstance().getDisplayMenu());
					menuBar.add(StandardMenuSupplier.getInstance().getWindowsMenu());
					menuBar.add(StandardMenuSupplier.getInstance().getStandardMenu("debug"));
					menuBar.add(Box.createHorizontalGlue());
					menuBar.add(StandardMenuSupplier.getInstance().getHelpMenu());
					frame.setJMenuBar(menuBar);

					resourceString = resourceBundle.getString(FRAME_TITLE_PATH);

					frame.setTitle(resourceString);

//					icon = Toolkit.getDefaultToolkit().getImage("icon.gif");
					frame.setIconImage(new ImageIcon(getClass().getClassLoader().getResource("insider.png"))); 

					
					frame.setSize(
						UserPreferencesSupplier.getInstance().getDecimal(WIDTH_PATH).intValue(),
						UserPreferencesSupplier.getInstance().getDecimal(HEIGHT_PATH).intValue()
					);
					frame.setExtendedState(UserPreferencesSupplier.getInstance().getDecimal(EXTENDED_STATE_PATH).intValue());
					frame.setVisible(true);

					NotificationSupplier.getInstance();

//					for (String filename : args) {
//						CurvesSupplier.getInstance().loadRawFile(new File(filename));
//					}
				} catch (Exception e) {
//					final String message = MessageFormat.format(Constants.RUNTIME_ERROR_FORMAT, e);
					_logger.log(Level.SEVERE, e.getMessage(), e);

					// try to properly shutdown the application in case of an uncaught exception
//					if (frame != null) {
//						frame.showErrorDialog(message);
//						frame.close();
//					}

					// Force exit with an error code
					// TODO : see why we MUST force the exit and why the program get stuck on caught exceptions
					// even though traces show that we exited both the run and the main methods 
					System.exit(-1);
				}
			}
		});
	}
}
